---
description: 'Securely store and retrieve secrets values with Nitric'
---

# Secrets

Nitric Secrets simplifies the secure storage, updating, and retrieval of sensitive information like database credentials and API keys.

Alternatively, you can choose to store these values as environment variables. Learn more about it [here](/reference/env).

If you're interested in the architecture, provisioning, or deployment steps, they can be found [here](/architecture/secrets).

## Definitions

### Secrets

Secrets refer to encrypted values stored in a secure Secrets Manager. They typically contain sensitive data like usernames and passwords required to access a database. Since credentials and keys tend to change over time, Nitric secrets act as a virtual storage location for these values with version control baked in.

### Versions

Each secret has a "latest" version, and it may also have historical versions of the stored value. This ensures that values such as encryption keys can be rotated without losing access to the key used to encrypt previously stored data.

### Values

Values are the specific secret data associated with a particular version of the secret. For example, it could be the current encryption key or the database credentials.

### Relationship between Secrets, Versions, and Values

The schema below illustrates the relationship between secrets, versions and values for a secret named db.password with two versions:

```
+- Secret [ 'db.password' ]
   |
   +- SecretVersion [ '7F5F86D0-D97F-487F-A5A0-11BAAD00F777' ]
   |  |
   |  +- SecretValue [ 'bleak_dearest_hanged_reigns' ]
   |
   +- SecretVersion [ '0581BBD9-C67F-4E8F-849D-38E52CAEE0EB' ]
      |
      +- SecretValue [ 'crummy_goofed_caddy_radiant' ]
```

## Create Secrets

Nitric enables you to define named secrets with customizable permissions. When defining a secret, you can specify permissions for putting or accessing secret versions within the secret. In the example below, we declare a secret named `api-key` and indicate that our service requires access to put and access secret versions within secret:

<CodeSwitcher tabs>

```javascript !!
import { secret } from '@nitric/sdk'

// Create a new secret
const apiKey = secret('api-key').allow('put', 'access')
```

```typescript !!
import { secret } from '@nitric/sdk'

// Create a new secret
const apiKey = secret('api-key').allow('put', 'access')
```

```python !!
from nitric.resources import secret
from nitric.application import Nitric

# Create a new secret
api_key = secret("api-key").allow("put", "access")

Nitric.run()
```

```go !!
import (
  "github.com/nitrictech/go-sdk/nitric"
  "github.com/nitrictech/go-sdk/nitric/secrets"
)

func main() {
  apiKey := nitric.NewSecret("api-key").Allow(secrets.SecretPut, secrets.SecretAccess)

  nitric.Run()
}
```

```dart !!
import 'package:nitric_sdk/nitric.dart';

// Create a new secret
final apiKey = Nitric.secret("api-key").allow([
  SecretPermission.put,
  SecretPermission.access,
]);
```

</CodeSwitcher>

## Storing a secret value

To store or update the latest version of a secret, use the `put()` method on the secret reference. The service must have permissions to `put` to the secret.

<CodeSwitcher tabs>

```javascript !!
import { secret } from '@nitric/sdk'

const apiKey = secret('api-key').allow('put')

const latestVersion = await apiKey.put('a new secret value')

// We can get the version ID of our newly stored value
latestVersion.version
```

```typescript !!
import { secret } from '@nitric/sdk'

const apiKey = secret('api-key').allow('put')

const latestVersion = await apiKey.put('a new secret value')

// We can get the version ID of our newly stored value
latestVersion.version
```

```python !!
from nitric.resources import secret
from nitric.application import Nitric

api_key = secret("api-key").allow("put")

latest = await api_key.put("a new secret value")

# We can get the version ID of our newly stored value
latest.version

Nitric.run()
```

```go !!
import (
  "context"

  "github.com/nitrictech/go-sdk/nitric"
  "github.com/nitrictech/go-sdk/nitric/secrets"
)

func main() {
  apiKey := nitric.NewSecret("api-key").Allow(secrets.SecretPut)

  // We can get the version ID of our newly stored value
  versionId, _ := apiKey.Put(context.TODO(), []byte("a new secret value"))

  nitric.Run()
}
```

```dart !!
import 'package:nitric_sdk/nitric.dart';

// Create a new secret
final apiKey = Nitric.secret("api-key").allow([
  SecretPermission.put,
]);

final latest = await apiKey.put("a new secret value");

// We can get the version ID of our newly stored value
latest.version
```

</CodeSwitcher>

<Note>
  Secret versioning is automatic. Every time you `put` a new secret value a new
  version will be created and set as the `latest` version.
</Note>

## Accessing a secret value

Accessing the contents of a secret version requires first getting a reference to it. There are two ways of getting a reference, either by using `latest()` to get the latest version or using `version()` to get a previous version. Getting the latest version is generally the best option for retrieving credentials or API keys, as the latest version is the only valid version.

<CodeSwitcher tabs>

```javascript !!
// Get a reference to the latest version
const latest = apiKey.latest()

// Get a reference to a specific version
const version = apiKey.version('7F5F86D0-D97F-487F')
```

```typescript !!
// Get a reference to the latest version
const latest = apiKey.latest()

// Get a reference to a specific version
const version = apiKey.version('7F5F86D0-D97F-487F')
```

```python !!
# Get a reference to the latest version
latest = api_key.latest()

# Get a reference to a specific version
version = api_key.version("7F5F86D0-D97F-487F")
```

```go !!
// golang does not have a SecretVersion object use the Secret.Access() and Secret.AccessVersion() methods
// available on the secret
```

```dart !!
// Get a reference to the latest version
final latest = apiKey.latest();

// Get a reference to a specific version
final version = apiKey.version("7F5F86D0-D97F-487F");
```

</CodeSwitcher>

Once the secret reference is obtained accessing the contents of the secret version can be done by calling the `access()` method.

<CodeSwitcher tabs>

```javascript !!
import { secret } from '@nitric/sdk'

const apiKey = secret('api-key').allow('access')

// Access the details of the latest version of a secret
const latest = await apiKey.latest().access()

// Retrieve the value of the secret as a string
const value = latest.asString()

// Retrieve the value of the secret as bytes
const bytes = latest.asBytes()
```

```typescript !!
import { secret } from '@nitric/sdk'

const apiKey = secret('api-key').allow('access')

// Access the details of the latest version of a secret
const latest = await apiKey.latest().access()

// Retrieve the value of the secret as a string
const value = latest.asString()

// Retrieve the value of the secret as bytes
const bytes = latest.asBytes()
```

```python !!
from nitric.resources import secret
from nitric.application import Nitric

api_key = secret("api-key").allow("access")

# Access the details of the latest version of a secret
latest = await api_key.latest().access()

# Retrieve the value of the secret as a string
value = latest.as_string()

# Retrieve the value of the secret as bytes
byteValue = latest.as_bytes()

Nitric.run()
```

```go !!
import (
  "context"

  "github.com/nitrictech/go-sdk/nitric"
  "github.com/nitrictech/go-sdk/nitric/secrets"
)

func main() {
  apiKey := nitric.NewSecret("api-key").Allow(secrets.SecretAccess)

  // Access the details of the latest version of a secret
  latest, _ := apiKey.Access(context.TODO())

  // Retrieve the value of the secret as a string
  value := latest.AsString()

  // Access the details of the latest version of a secret
  someVersion, _ := apiKey.AccessVersion(context.TODO(), "known-version-id")

  otherValue := someVersion.AsString()

  nitric.Run()
}
```

```dart !!
import 'package:nitric_sdk/nitric.dart';

final apiKey = Nitric.secret("api-key").allow([
  SecretPermission.access,
]);

// Access the details of the latest version of a secret
final latest = await apiKey.latest().access();

// Retrieve the value of the secret as a string
final value = latest.value;
```

</CodeSwitcher>

## Cloud Service Mapping

Each cloud provider comes with a set of default services used when deploying resources. You can find the default services for each cloud provider below.

- [AWS](/providers/mappings/aws/secrets)
- [Azure](/providers/mappings/azure/secrets)
- [Google Cloud](/providers/mappings/gcp/secrets)
